<route lang="json5">
{
  style: {
    navigationBarTitleText: '约会记录'
  }
}
</route>

<script lang="ts" setup>
import { ref, computed, onMounted } from 'vue'
import { useSupabaseCoupleStore } from '@/store/supabaseCouple'
import { useToast } from 'wot-design-uni'
import dayjs from 'dayjs'
import type { DateRecord } from '@/types/couple'

// 移除 H5 下的 supabase 依赖，专注小程序端直传 Storage

defineOptions({ name: 'DateRecords' })

const coupleStore = useSupabaseCoupleStore()
const { success: showSuccess, error: showError } = useToast()

const showAdd = ref(false)
const showDatePicker = ref(false)
const showEditDatePicker = ref(false)
const form = ref<Partial<DateRecord>>({
  title: '',
  date: dayjs().format('YYYY-MM-DD'),
  location: '',
  description: '',
  photos: [],
  mood: 5,
  cost: undefined,
  tags: [],
})

// 用于日期选择器的临时变量（时间戳）
const tempDate = ref(Date.now())

const isUploading = ref(false)

const moodOptions = [
  { label: '非常开心', value: 5 },
  { label: '开心', value: 4 },
  { label: '一般', value: 3 },
  { label: '有点糟', value: 2 },
  { label: '糟糕', value: 1 },
]

const tagInput = ref('')
function addTag(record: Partial<DateRecord>) {
  const v = tagInput.value.trim()
  if (!v)
    return
  if (!record.tags)
    record.tags = []
  if (!record.tags.includes(v))
    record.tags.push(v)
  tagInput.value = ''
}
function removeTag(record: Partial<DateRecord>, t: string) {
  if (!record.tags)
    return
  record.tags = record.tags.filter(x => x !== t)
}

// 处理日期选择
function handleDateConfirm() {
  const val = dayjs(tempDate.value).format('YYYY-MM-DD')
  form.value.date = val
  showDatePicker.value = false
}

function handleEditDateConfirm() {
  const val = dayjs(tempDate.value).format('YYYY-MM-DD')
  editForm.value.date = val
  showEditDatePicker.value = false
}

// --- Image Handling ---
async function handleChooseImage(record: Partial<DateRecord>) {
  const currentPhotosCount = record.photos?.length || 0
  if (currentPhotosCount >= 9) {
    showError('最多只能上传9张图片')
    return
  }

  try {
    // 仅小程序：使用 chooseMedia 选择图片
    const resMedia: any = await uni.chooseMedia({
      count: 9 - currentPhotosCount,
      mediaType: ['image'],
      sourceType: ['album', 'camera'],
    })
    if (!record.photos)
      record.photos = []
    const paths = (resMedia?.tempFiles || []).map((f: any) => f.tempFilePath)
    ;(record.photos as any[]).push(...paths)
  }
  catch (err) {
    console.log('用户取消了图片选择', err)
  }
}

function handleRemoveImage(record: Partial<DateRecord>, index: number) {
  record.photos?.splice(index, 1)
}

function getPhotoUrl(photo: any): string {
  // #ifdef H5
  if (photo instanceof File) {
    return URL.createObjectURL(photo)
  }
  // #endif
  return photo
}

function handlePreviewImage(photos: any[], current: any) {
  const urls = photos.map(p => getPhotoUrl(p))
  const currentUrl = getPhotoUrl(current)
  uni.previewImage({
    urls,
    current: currentUrl,
  })
}

// 小程序端：压缩图片
async function compressImageMp(path: string, quality = 70): Promise<string> {
  return await new Promise<string>((resolve, reject) => {
    // 显示压缩提示（会被后续上传提示覆盖）
    uni.showLoading({ title: '压缩中...', mask: true })
    uni.compressImage({
      src: path,
      quality,
      success: (res) => {
        const out = (res as any).tempFilePath || path
        resolve(out)
      },
      fail: reject,
    })
  })
}

async function uploadPhotos(photos: any[]): Promise<string[]> {
  isUploading.value = true
  try {
    uni.showLoading({ title: '上传中...', mask: true })
    const total = photos.length
    let finished = 0

    const uploadPromises = photos.map(async (photo) => {
      // 仅保留微信小程序上传逻辑：使用 REST 接口 + uni.uploadFile 上传到 images bucket
      const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
      const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

      const photoPathMp = photo as string
      // 先压缩
      const compressedPath = await compressImageMp(photoPathMp, 70)
      const extMp = compressedPath.substring(compressedPath.lastIndexOf('.')) || photoPathMp.substring(photoPathMp.lastIndexOf('.'))
      const nameMp = `date-record-${Date.now()}${extMp}`

      const uploadUrl = `${supabaseUrl}/storage/v1/object/images/${encodeURIComponent(nameMp)}`
      await new Promise<void>((resolve, reject) => {
        const task = uni.uploadFile({
          url: uploadUrl,
          filePath: compressedPath,
          name: 'file',
          header: {
            'Authorization': `Bearer ${supabaseAnonKey}`,
            'Cache-Control': '3600',
            'x-upsert': 'false',
          },
          success: (res) => {
            if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
              finished += 1
              uni.showLoading({ title: `上传中 ${finished}/${total}`, mask: true })
              resolve()
            }
            else {
              reject(new Error(`上传失败: ${res.statusCode}`))
            }
          },
          fail: reject,
        })
        // 单文件进度（简单覆盖提示）
        task.onProgressUpdate?.((p) => {
          uni.showLoading({ title: `上传中 ${p.progress}%`, mask: true })
        })
      })
      return `${supabaseUrl}/storage/v1/object/public/images/${encodeURIComponent(nameMp)}`
    })

    const result = await Promise.all(uploadPromises)
    return result
  }
  finally {
    uni.hideLoading()
    isUploading.value = false
  }
}

async function submit() {
  if (!form.value.title)
    return showError('请输入标题')

  try {
    const uploadedPhotos = await uploadPhotos(form.value.photos || [])
    await coupleStore.addDateRecord({
      title: form.value.title!,
      date: form.value.date || dayjs().format('YYYY-MM-DD'),
      location: form.value.location || '',
      description: form.value.description || '',
      photos: uploadedPhotos,
      mood: (form.value.mood || 5) as 1 | 2 | 3 | 4 | 5,
      cost: form.value.cost,
      weather: '',
      tags: form.value.tags || [],
    })
    showAdd.value = false
    form.value = { title: '', date: dayjs().format('YYYY-MM-DD'), location: '', description: '', photos: [], mood: 5, cost: undefined, tags: [] }
    showSuccess('已添加约会记录')
  }
  catch (err) {
    showError('添加失败，请重试')
  }
}

// 编辑/删除
const showEdit = ref(false)
const editingId = ref<string | null>(null)
const editForm = ref<Partial<DateRecord>>({})

function openOps(item: DateRecord) {
  uni.showActionSheet({
    itemList: ['编辑', '删除', '取消'],
    success: (res) => {
      if (res.tapIndex === 0)
        beginEdit(item)
      else if (res.tapIndex === 1)
        confirmRemove(item)
    },
  })
}

function beginEdit(item: DateRecord) {
  editingId.value = item.id
  // 深拷贝，防止直接修改原对象
  editForm.value = JSON.parse(JSON.stringify({ ...item, mood: String(item.mood) }))
  // 设置编辑时的时间戳
  tempDate.value = item.date ? dayjs(item.date).valueOf() : Date.now()
  showEdit.value = true
}

async function submitEditRecord() {
  if (!editingId.value)
    return

  try {
    // 处理图片：区分已上传的图片和新选择的本地图片
    // 已上传的图片应该是以 supabase.co 开头的URL
    const existingPhotos = editForm.value.photos?.filter(photo =>
      typeof photo === 'string' && photo.includes('supabase.co'),
    ) || []

    // 新选择的图片可能是 tempFilePath 或 http://tmp/ 格式
    const newLocalPhotos = editForm.value.photos?.filter(photo =>
      typeof photo === 'string' && !photo.includes('supabase.co'),
    ) || []

    let uploadedPhotos: string[] = []
    if (newLocalPhotos.length > 0) {
      uploadedPhotos = await uploadPhotos(newLocalPhotos)
    }

    const allPhotos = [...existingPhotos, ...uploadedPhotos]

    const finalRecord = { ...editForm.value, photos: allPhotos }
    await coupleStore.updateDateRecord(editingId.value, finalRecord)
    showEdit.value = false
    editingId.value = null
    showSuccess('已更新')
  }
  catch (err) {
    console.error('编辑失败:', err)
    showError('更新失败，请重试')
  }
}

function confirmRemove(item: DateRecord) {
  uni.showModal({
    title: '删除确认',
    content: `确定删除"${item.title}"吗？`,
    success: async ({ confirm }) => {
      if (confirm) {
        await coupleStore.removeDateRecord(item.id)
        showSuccess('已删除')
      }
    },
  })
}

const records = computed(() => coupleStore.dateRecords)

// 格式化日期显示
function formatDate(date: string | Date): string {
  if (!date)
    return ''
  return dayjs(date).format('YYYY年MM月DD日')
}

// 格式化日期用于弹窗显示
function formatDateForCell(date: string | Date): string {
  if (!date)
    return '请选择日期'
  return dayjs(date).format('YYYY-MM-DD')
}

onMounted(() => {
  if (!coupleStore.profile) {
    coupleStore.initProfile()
  }
})
</script>

<template>
  <view class="date-container">
    <!-- 添加按钮 -->
    <view class="toolbar">
      <wd-button type="primary" @click="showAdd = true">
        <wd-icon name="add" size="16px" /> 记录一次约会
      </wd-button>
    </view>

    <!-- 列表 -->
    <view class="list">
      <view v-for="item in records" :key="item.id" class="card">
        <view class="hd">
          <view class="title">
            {{ item.title }}
          </view>
          <view class="time">
            {{ formatDate(item.date) }}
          </view>
        </view>
        <view v-if="item.location" class="row">
          <wd-icon name="location" size="14px" color="#888" />
          <text class="text">{{ item.location }}</text>
        </view>
        <view v-if="item.description" class="desc">
          {{ item.description }}
        </view>

        <view v-if="item.photos?.length" class="photos">
          <image
            v-for="(photo, idx) in item.photos" :key="idx" :src="getPhotoUrl(photo)" class="photo" mode="aspectFill"
            @click="handlePreviewImage(item.photos, photo)"
          />
        </view>

        <view class="footer">
          <view class="mood">
            心情：{{ item.mood }} / 5
          </view>
          <view class="tags">
            <wd-tag v-for="t in item.tags" :key="t" size="small" type="primary" style="margin-right:6px">
              {{ t }}
            </wd-tag>
          </view>
          <view class="ops">
            <wd-button size="small" plain @click="openOps(item)">
              更多
            </wd-button>
          </view>
        </view>
      </view>

      <view v-if="records.length === 0" class="empty">
        <wd-icon name="location" size="64px" color="#ccc" />
        <text class="tip">还没有约会记录，点击上方按钮开始记录吧</text>
      </view>
    </view>

    <!-- 添加弹窗 -->
    <wd-popup v-model="showAdd" position="bottom" :safe-area-inset-bottom="true">
      <view class="dialog">
        <view class="dialog-hd">
          <view class="title">
            新增约会
          </view>
          <wd-icon name="close" @click="showAdd = false" />
        </view>
        <view class="dialog-bd">
          <wd-cell-group>
            <wd-input v-model="form.title" label="标题" placeholder="例如：看电影/海边散步" required />
            <wd-cell title="日期" :value="formatDateForCell(form.date)" is-link @click="showDatePicker = true; tempDate = form.date ? dayjs(form.date).valueOf() : Date.now()" />
            <wd-input v-model="form.location" label="地点" placeholder="约会地点" />
            <wd-picker v-model="form.mood" label="心情" :columns="moodOptions" />
            <wd-input v-model="form.cost" label="花费" type="number" placeholder="本次约会花费（可选）" />
            <wd-textarea v-model="form.description" label="描述" placeholder="记录一些感受（可选）" :auto-height="true" />
          </wd-cell-group>

          <!-- 照片上传 -->
          <view class="photo-uploader">
            <view class="up-title">
              添加照片
            </view>
            <view class="photo-grid">
              <view v-for="(photo, index) in form.photos" :key="index" class="photo-item">
                <image :src="getPhotoUrl(photo)" mode="aspectFill" class="preview-img" @click="handlePreviewImage(form.photos, photo)" />
                <view class="remove-icon" @click="handleRemoveImage(form, index)">
                  <wd-icon name="close-bold" color="#fff" />
                </view>
              </view>
              <view v-if="(form.photos?.length || 0) < 9" class="add-photo-btn" @click="handleChooseImage(form)">
                <wd-icon name="add" size="36px" color="#ccc" />
              </view>
            </view>
          </view>

          <!-- 标签 -->
          <view class="tags-input">
            <wd-input v-model="tagInput" label="标签" placeholder="输入后回车添加" @confirm="addTag(form)" />
            <view class="tag-list">
              <wd-tag v-for="t in form.tags" :key="t" type="primary" size="small" custom-class="tag-chip" closeable @close="removeTag(form, t)">
                {{ t }}
              </wd-tag>
            </view>
          </view>
        </view>
        <view class="dialog-ft">
          <wd-button @click="showAdd = false">
            取消
          </wd-button>
          <wd-button type="primary" @click="submit">
            保存
          </wd-button>
        </view>
      </view>
    </wd-popup>

    <!-- 编辑弹窗 -->
    <wd-popup v-model="showEdit" position="bottom" :safe-area-inset-bottom="true">
      <view class="dialog">
        <view class="dialog-hd">
          <view class="title">
            编辑约会
          </view>
          <wd-icon name="close" @click="showEdit = false" />
        </view>
        <view class="dialog-bd">
          <wd-cell-group>
            <wd-input v-model="editForm.title" label="标题" required />
            <wd-cell title="日期" :value="formatDateForCell(editForm.date)" is-link @click="showEditDatePicker = true; tempDate = editForm.date ? dayjs(editForm.date).valueOf() : Date.now()" />
            <wd-input v-model="editForm.location" label="地点" />
            <wd-picker v-model="editForm.mood" label="心情" :columns="moodOptions" />
            <wd-input v-model="editForm.cost" label="花费" type="number" />
            <wd-textarea v-model="editForm.description" label="描述" :auto-height="true" />
            <!-- Photos -->
            <view class="photo-uploader">
              <view class="photo-grid">
                <view v-for="(photo, index) in editForm.photos" :key="index" class="photo-item">
                  <image :src="getPhotoUrl(photo)" mode="aspectFill" class="preview-img" @click="handlePreviewImage(editForm.photos, photo)" />
                  <view class="remove-icon" @click="handleRemoveImage(editForm, index)">
                    <wd-icon name="close-bold" color="#fff" />
                  </view>
                </view>
                <view v-if="(editForm.photos?.length || 0) < 9" class="add-photo-btn" @click="handleChooseImage(editForm)">
                  <wd-icon name="add" size="24px" color="#ccc" />
                </view>
              </view>
            </view>
          </wd-cell-group>
        </view>
        <view class="dialog-ft">
          <wd-button @click="showEdit = false">
            取消
          </wd-button>
          <wd-button type="primary" @click="submitEditRecord">
            保存
          </wd-button>
        </view>
      </view>
    </wd-popup>

    <!-- 日期选择器 -->
    <wd-popup v-model="showDatePicker" position="bottom">
      <wd-datetime-picker-view
        v-model="tempDate"
        type="date"
      />
      <view class="picker-actions">
        <wd-button @click="showDatePicker = false">
          取消
        </wd-button>
        <wd-button type="primary" @click="handleDateConfirm">
          确定
        </wd-button>
      </view>
    </wd-popup>

    <!-- 编辑日期选择器 -->
    <wd-popup v-model="showEditDatePicker" position="bottom">
      <wd-datetime-picker-view
        v-model="tempDate"
        type="date"
      />
      <view class="picker-actions">
        <wd-button @click="showEditDatePicker = false">
          取消
        </wd-button>
        <wd-button type="primary" @click="handleEditDateConfirm">
          确定
        </wd-button>
      </view>
    </wd-popup>

    <wd-toast />
  </view>
</template>

<style scoped lang="scss">
.date-container {
  min-height: 100vh;
  background-color: #fff0f5;
  background-image: radial-gradient(circle at 25% 25%, rgba(255, 228, 225, 0.4) 2px, transparent 0),
    radial-gradient(circle at 75% 75%, rgba(255, 228, 225, 0.4) 2px, transparent 0);
  background-size: 20px 20px;
}

.toolbar {
  padding: 12px 16px;
  background: rgba(255, 255, 255, 0.75);
  backdrop-filter: blur(15px);
  border-bottom: 1px solid rgba(255, 135, 171, 0.15);
  position: sticky;
  top: 0;
  z-index: 100;
}

.list {
  padding: 16px;
}

.card {
  background: #ffffff;
  border-radius: 24px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 4px 16px rgba(255, 105, 180, 0.1), 0 10px 30px rgba(255, 105, 180, 0.15);
  border: 1px solid white;
}

.hd {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 8px;
}

.title {
  font-size: 18px;
  font-weight: bold;
  color: #444;
}

.time {
  font-size: 12px;
  color: #b0a8b9;
  flex-shrink: 0;
  margin-left: 12px;
}

.row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0;
}

.text {
  font-size: 14px;
  color: #777;
}

.desc {
  font-size: 14px;
  color: #666;
  line-height: 1.7;
  margin: 12px 0;
}

.photos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 12px;
}

.photo {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 18px;
}

.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #fdf2f5;
}

.mood {
  font-size: 12px;
  color: #ff69b4;
  background-color: #fff0f5;
  padding: 5px 12px;
  border-radius: 16px;
  border: 1px solid #ffdde5;
}

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 80px 0;
  color: #c0b8c8;
}

.tip {
  margin-top: 16px;
  font-size: 14px;
}

.dialog {
  background: #fff;
  border-radius: 24px 24px 0 0;
}

.dialog-hd {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid #f5f5f5;
  font-size: 18px;
  font-weight: bold;
  color: #444;
}

.dialog-bd {
  padding: 16px;
}

.up-title {
  font-size: 16px;
  font-weight: bold;
  color: #555;
  margin-bottom: 12px;
}

.tag-list {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.dialog-ft {
  display: flex;
  gap: 12px;
  padding: 16px;
  border-top: 1px solid #f5f5f5;
}

/* 照片上传区域 */
.photo-uploader {
  margin-top: 16px;
}

.photo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.photo-item {
  position: relative;
  width: 100%;
  padding-top: 100%;
  border-radius: 18px;
  overflow: hidden;
  background: #fdf2f5;
}

.preview-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.remove-icon {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
}

.add-photo-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 18px;
  border: 2px dashed #ffdde5;
  background: #fffafa;
}

.picker-actions {
  display: flex;
  gap: 12px;
  padding: 16px;
  background: white;
  border-top: 1px solid #f5f5f5;
}
</style>
